package site.addzero.cli.platform

import org.koin.core.annotation.Single
import site.addzero.cli.platform.ProUtil.handleProcessOutput
import java.io.File
import java.util.concurrent.TimeUnit

/**
 * Windows平台工具实现
 */
@Single
class WindowsPlatformStrategy : PlatformStrategy, PortStrategy {
    override val support: Boolean
        get() = run {
            val osName = System.getProperty("os.name").lowercase()
            osName.contains("win")
        }

    override fun setEnv(name: String, value: String) {
        // setx命令格式：setx 变量名 "变量值"
        val process = ProcessBuilder("cmd.exe", "/c", "setx", name, value)
            .redirectErrorStream(true)
            .start()

        handleProcessOutput(process)
        val exitCode = process.waitFor()
        if (exitCode != 0) {
            System.err.println("Windows设置环境变量失败，错误码: " + exitCode)
        }
        println("Windows环境变量设置成功（需重启终端生效）: " + name + "=" + value)
    }


    override fun executeCommand(command: String, timeout: Long): CommandResult {
        return try {
            // 使用PowerShell而不是cmd来执行命令
            val process = ProcessBuilder("powershell", "-Command", command).start()
            val finished = process.waitFor(timeout, TimeUnit.MILLISECONDS)

            if (finished) {
                val exitCode = process.exitValue()
                val output = process.inputStream.bufferedReader().use { it.readText() }
                CommandResult(exitCode, output, "")

            } else {
                process.destroyForcibly()
                CommandResult(-1, "Command timed out", "")
            }
        } catch (e: Exception) {
            CommandResult(-1, "Error executing command: ${e.message}", "Error executing command: ${e.message}")
        }
    }

    override fun getPlatformType(): PlatformType {
        return PlatformType.WINDOWS
    }

    override fun killPort(port: Int): Boolean {
        // 使用PowerShell命令终止端口占用进程
        val command =
            "Get-NetTCPConnection -LocalPort $port -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id \$_.OwningProcess -Force }"
        val result = executeCommand(command)
        
        // 如果PowerShell命令执行失败，尝试使用传统的netstat和taskkill命令
        if (!result.isSuccess()) {
            val fallbackCommand = "for /f \"tokens=5\" %a in ('netstat -aon ^| findstr :$port') do taskkill /PID %a /F 2>nul"
            val fallbackResult = executeCommand(fallbackCommand)
            return fallbackResult.isSuccess()
        }
        
        return result.isSuccess()
    }

    override fun showPort(port: Int): String {
        // Windows平台使用PowerShell命令查看端口占用
        val command = "Get-NetTCPConnection -LocalPort $port -ErrorAction SilentlyContinue | ForEach-Object { Write-Output \"Port $port used by \$($(Get-Process -Id \$\$_.OwningProcess -ErrorAction SilentlyContinue).ProcessName) (PID: \$\$_.OwningProcess)\" }"
        val result = executeCommand(command)
        
        return if (result.isSuccess() && result.output.isNotBlank()) {
            result.output
        } else {
            "端口 $port 未被占用"
        }
    }
}
